package com.blogs.tools;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.blogs.entity.AppConfig;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.widget.ImageView;

public class ImageDownLoad {
	// 为了加快速度，在内存中开启缓存（主要应用于重复图片较多时，或者同一个图片要多次被访问，比如在ListView时来回滚动）
	public static Map<String, SoftReference<Bitmap>> imageCache = new HashMap<String, SoftReference<Bitmap>>();

	private static ExecutorService executorService = Executors.newFixedThreadPool(5); // 固定五个线程来执行任务
	private static final Handler handler = new Handler();

	/**
	 * 
	 * @param imageUrl
	 *            图像url地址 回调接口
	 * @return 返回内存中缓存的图像，第一次加载返回null
	 */
	public static void loadDrawable(final String imageUrl, final ImageView iv) {
		Log.i("imageUrl", imageUrl);
		// 如果缓存过就从缓存中取出数据
		if (imageCache.containsKey(imageUrl)) {
			SoftReference<Bitmap> softReference = imageCache.get(imageUrl);
			if (softReference.get() != null) {
//				iv.setImageDrawable(softReference.get());
				iv.setImageBitmap(softReference.get());
				return;
			}
		}
		// 缓存中没有图像，则从网络上取出数据，并将取出的数据缓存到内存中
		executorService.submit(new Runnable() {
			public void run() {
				try {
					final Drawable drawable = loadImageFromUrl(imageUrl);
					
					imageCache.put(imageUrl, new SoftReference<Bitmap>(Tools.drawableToBitmap(drawable)));

					handler.post(new Runnable() {
						public void run() {
							iv.setImageDrawable(drawable);
						}
					});
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}
		});
	}

	/**
	 * @param imageUrl
	 *            图像url地址
	 * @param callback
	 *            回调接口
	 * @return 返回内存中缓存的图像，第一次加载返回null
	 * **/
	public static void loadDrawable(final String imageUrl, final ImageCallBack callback) {
		Log.i("imageUrl", imageUrl);
		if (imageCache.containsKey(imageUrl)) {
			SoftReference<Bitmap> softReference = imageCache.get(imageUrl);
			if (softReference.get() != null) {
				Bitmap bitmap = softReference.get();
				callback.onSuccess(bitmap);
				return;
			}
		}
		// 缓存中没有图像，则从网络上取出数据，并将取出的数据缓存到内存中
		executorService.submit(new Runnable() {
			public void run() {
				try {
					final Bitmap bitmap=loadImageFromUrlHttp(imageUrl);

					imageCache.put(imageUrl, new SoftReference<Bitmap>(bitmap));

					handler.post(new Runnable() {
						public void run() {
							callback.onSuccess(bitmap);
						}
					});
				} catch (Exception e) {
					callback.onFailed();
					throw new RuntimeException(e);
				}
			}
		});
	}

	public static void loadDrawable(final String imageUrl, final String file_name, final ImageCallBack callback) {
		if (imageCache.containsKey(imageUrl)) {
			SoftReference<Bitmap> softReference = imageCache.get(imageUrl);
			if (softReference.get() != null) {
				Bitmap bitmap = softReference.get();
				callback.onSuccess(bitmap);
				return;
			}
		}
		final String path = "/sdcard/" + AppConfig.SD_CARD_FOLDER + "/";
		File img = new File(path + file_name);

		if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {

			if (img.exists()) {
				try {
					FileInputStream inputStream = new FileInputStream(img);
					int i = -1;
					// org.apache.commons.io.output.ByteArrayOutputStream
					ByteArrayOutputStream baos = new ByteArrayOutputStream();
					while ((i = inputStream.read()) != -1) {
						baos.write(i);
					}
					byte[] b = baos.toByteArray();
					callback.onSuccess(BitmapFactory.decodeByteArray(b, 0, b.length));
				} catch (Exception e) {
					// TODO Auto-generated catch block
					callback.onFailed();
				}
			} else {
				executorService.submit(new Runnable() {
					public void run() {
						try {
							final Bitmap bitmap=loadImageFromUrlHttp(imageUrl);
							imageCache.put(imageUrl, new SoftReference<Bitmap>(bitmap));
							ByteArrayOutputStream baos = new ByteArrayOutputStream();
							bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
							byte[] b = baos.toByteArray();
							final File dir = new File(path);
							if (!dir.exists())
								dir.mkdir();
							FileOutputStream fos = new FileOutputStream(path + file_name);
							fos.write(b);
							fos.close();
							handler.post(new Runnable() {
								public void run() {
									callback.onSuccess(bitmap);
								}
							});
						} catch (Exception e) {
							callback.onFailed();
							throw new RuntimeException(e);
						}
					}
				});
			}
		} else {
			executorService.submit(new Runnable() {
				public void run() {
					try {
						final Bitmap bitmap=loadImageFromUrlHttp(imageUrl);

						imageCache.put(imageUrl, new SoftReference<Bitmap>(bitmap));

						handler.post(new Runnable() {
							public void run() {
								callback.onSuccess(bitmap);
							}
						});
					} catch (Exception e) {
						callback.onFailed();
						throw new RuntimeException(e);
					}
				}
			});
		}
	}

	/**
	 * 
	 * @param imageUrl
	 *            图像url地址
	 * @param callback
	 *            回调接口
	 * @return 返回内存中缓存的图像，第一次加载返回null
	 */
	public static void loadDrawable(final String imageUrl, final ImageView iv, final ImageCallBack callback) {
		Log.i("imageUrl", imageUrl);
		// 如果缓存过就从缓存中取出数据
		if (imageCache.containsKey(imageUrl)) {
			SoftReference<Bitmap> softReference = imageCache.get(imageUrl);
			if (softReference.get() != null) {
//				iv.setImageDrawable(softReference.get());
				iv.setImageBitmap(softReference.get());
				callback.onSuccess();
				return;
			}
		}
		// 缓存中没有图像，则从网络上取出数据，并将取出的数据缓存到内存中
		executorService.submit(new Runnable() {
			public void run() {
				try {
					final Drawable drawable = loadImageFromUrl(imageUrl);

					imageCache.put(imageUrl, new SoftReference<Bitmap>(Tools.drawableToBitmap(drawable)));

					handler.post(new Runnable() {
						public void run() {
							iv.setImageDrawable(drawable);
							callback.onSuccess();
						}
					});
				} catch (Exception e) {
					callback.onFailed();
					throw new RuntimeException(e);
				}
			}
		});
	}

	// 从网络上取数据方法,压缩下载
	protected static Drawable loadImageFromUrl(String imageUrl) {
		try {

			return Drawable.createFromStream(new URL(imageUrl).openStream(), "image.png");
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	//利用http协议从网络下载图片,高清
	protected static Bitmap loadImageFromUrlHttp(String imageUrl)
	{
		URL url=null;
		byte[] b=null;
		int responsecode=0;
		HttpURLConnection httpurlconnection=null;
		try {
			url = new URL(imageUrl);
			httpurlconnection = (HttpURLConnection) url.openConnection();
			httpurlconnection.setRequestMethod("GET");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
		httpurlconnection.setRequestProperty("Accept","image/png,image/*;q=0.8,*/*;q=0.5");
		httpurlconnection.setRequestProperty("Accept-Encoding","gzip,deflate");
		httpurlconnection.setRequestProperty("Accept-Language","zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3");
		httpurlconnection.setRequestProperty("Connection","keep-alive");
		httpurlconnection.setRequestProperty("Host",url.getHost());
		httpurlconnection.setRequestProperty("User-Agent","Mozilla/5.0");
		httpurlconnection.setConnectTimeout(1000);
		httpurlconnection.setReadTimeout(1000);
		try {
			httpurlconnection.connect();
			responsecode = httpurlconnection.getResponseCode();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
		InputStream result=null;
		if(responsecode == HttpURLConnection.HTTP_OK) //对应HTTP响应中状态行的响应码
		{
			try {
				result=httpurlconnection.getInputStream();
				
				int i = -1;
				//org.apache.commons.io.output.ByteArrayOutputStream
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				while ((i = result.read()) != -1) {
					baos.write(i);
				}
				b=baos.toByteArray();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return null;
			}
		}
		if (httpurlconnection != null) 
		{
		   httpurlconnection.disconnect();
		}
		return BitmapFactory.decodeByteArray(b, 0, b.length);
	}

	public interface ImageCallBack {
		public void onSuccess(Bitmap bitmap);

		public void onSuccess();

		public void onFailed();
	}

}
